from datetime import datetime, date
from typing import Dict, Any, List, Optional, Set
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import and_, or_, desc, func
import uuid

from models import Report, FileUpload, Merchant, IntegratedReport
import schemas
from services import file_service

def generate_report_code(db: Session, report_date: Any) -> str:
    """
    生成报告编号
    
    Args:
        db: 数据库会话
        report_date: 报告日期
        
    Returns:
        报告编号
    """
    # 转换日期格式
    if isinstance(report_date, str):
        try:
            report_date = datetime.strptime(report_date, '%Y-%m-%d').date()
        except ValueError:
            # 如果日期格式错误，使用当前日期
            report_date = datetime.now().date()
    elif not isinstance(report_date, date):
        report_date = datetime.now().date()
    
    # 计算当天的报告数量
    day_count = db.query(func.count(Report.id)).filter(
        Report.report_date == report_date
    ).scalar() or 0
    
    # 生成报告编号：前缀 + 日期 + 流水号
    prefix = "RPT"
    date_str = report_date.strftime('%Y%m%d')
    sequence = str(day_count + 1).zfill(3)
    
    return f"{prefix}-{date_str}-{sequence}"

def create_report(db: Session, report_data: Dict[str, Any]) -> Report:
    """
    创建报告
    
    Args:
        db: 数据库会话
        report_data: 报告数据
        
    Returns:
        创建的报告
    """
    # 处理日期格式
    if isinstance(report_data["report_date"], str):
        try:
            report_date = datetime.strptime(report_data["report_date"], '%Y-%m-%d').date()
        except ValueError:
            # 如果日期格式错误，使用当前日期
            report_date = datetime.now().date()
    else:
        report_date = report_data["report_date"]
    
    # 生成报告编号
    report_code = generate_report_code(db, report_date)
    
    # 创建报告
    report = Report(
        merchant_id=report_data["merchant_id"],
        report_code=report_code,
        report_name=report_data["report_name"],
        report_date=report_date,
        expected_file_count=report_data.get("expected_file_count", 2),
        operator=report_data.get("operator"),
        remark=report_data.get("remark"),
        status=0,  # 初始状态为未完成
        file_count=0  # 初始文件数量为0
    )
    
    db.add(report)
    db.commit()
    db.refresh(report)
    
    return report

def get_report_list(db: Session, filters: Dict[str, Any], date_range: Dict[str, Any], page_num: int, page_size: int) -> Dict[str, Any]:
    """
    获取报告列表
    
    Args:
        db: 数据库会话
        filters: 过滤条件
        date_range: 日期范围
        page_num: 页码
        page_size: 每页记录数
        
    Returns:
        报告列表
    """
    # 构建查询条件
    query = db.query(Report, Merchant.name.label("merchant_name")).join(
        Merchant, Report.merchant_id == Merchant.id
    )
    
    # 应用过滤条件
    for key, value in filters.items():
        if hasattr(Report, key):
            query = query.filter(getattr(Report, key) == value)
    
    # 应用日期范围
    if "start_date" in date_range:
        query = query.filter(Report.report_date >= date_range["start_date"])
    if "end_date" in date_range:
        query = query.filter(Report.report_date <= date_range["end_date"])
    
    # 获取总记录数
    total = query.count()
    
    # 分页
    query = query.order_by(desc(Report.report_date), desc(Report.created_at))
    query = query.offset((page_num - 1) * page_size).limit(page_size)
    
    # 执行查询
    results = query.all()
    
    # 构建返回数据
    reports = []
    for report, merchant_name in results:
        reports.append({
            "reportId": report.id,
            "reportCode": report.report_code,
            "merchantId": report.merchant_id,
            "merchantName": merchant_name,
            "reportName": report.report_name,
            "reportDate": report.report_date.strftime("%Y-%m-%d"),
            "status": report.status,
            "fileCount": report.file_count,
            "expectedFileCount": report.expected_file_count,
            "createTime": report.created_at.strftime("%Y-%m-%d %H:%M:%S")
        })
    
    return {
        "total": total,
        "pageNum": page_num,
        "pageSize": page_size,
        "list": reports
    }

def get_report_detail(db: Session, report_id: int) -> Optional[Dict[str, Any]]:
    """
    获取报告详情
    
    Args:
        db: 数据库会话
        report_id: 报告ID
        
    Returns:
        报告详情
    """
    # 查询报告信息
    report = db.query(Report).filter(Report.id == report_id).first()
    if not report:
        return None
    
    # 获取商户信息
    merchant = db.query(Merchant).filter(Merchant.id == report.merchant_id).first()
    
    # 获取关联的文件
    files = db.query(FileUpload).filter(
        FileUpload.report_id == report_id,
        FileUpload.status == 1
    ).order_by(FileUpload.file_type, desc(FileUpload.upload_time)).all()
    
    # 获取整合报告
    integrated = db.query(IntegratedReport).filter(
        IntegratedReport.report_id == report_id,
        IntegratedReport.status == 1
    ).first()
    
    # 构建文件列表
    file_list = []
    for file in files:
        file_list.append({
            "fileId": file.id,
            "fileName": file.file_name,
            "fileType": file.file_type,
            "fileSize": file.file_size,
            "storeType": file.store_type,
            "uploadTime": file.upload_time.strftime("%Y-%m-%d %H:%M:%S"),
            "operator": file.operator
        })
    
    # 构建整合报告信息
    integrated_info = None
    if integrated:
        integrated_info = {
            "id": integrated.id,
            "fileName": integrated.file_name,
            "fileSize": integrated.file_size,
            "integrationTime": integrated.integration_time.strftime("%Y-%m-%d %H:%M:%S")
        }
    
    # 构建返回数据
    return {
        "reportId": report.id,
        "reportCode": report.report_code,
        "merchantId": report.merchant_id,
        "merchantName": merchant.name if merchant else "",
        "reportName": report.report_name,
        "reportDate": report.report_date.strftime("%Y-%m-%d"),
        "status": report.status,
        "fileCount": report.file_count,
        "expectedFileCount": report.expected_file_count,
        "createTime": report.created_at.strftime("%Y-%m-%d %H:%M:%S"),
        "files": file_list,
        "integratedReport": integrated_info
    }

def integrate_report(db: Session, report_id: int, operator: str) -> Optional[IntegratedReport]:
    """
    整合报告
    
    Args:
        db: 数据库会话
        report_id: 报告ID
        operator: 操作人
        
    Returns:
        整合后的报告记录
    """
    # 查询报告信息
    report = db.query(Report).filter(Report.id == report_id).first()
    if not report:
        return None
    
    # 查询关联的文件
    files = db.query(FileUpload).filter(
        FileUpload.report_id == report_id,
        FileUpload.status == 1
    ).order_by(FileUpload.file_type).all()
    
    # 检查文件是否足够
    if len(files) < report.expected_file_count:
        return None
    
    # 将旧的整合报告标记为无效
    old_integrated = db.query(IntegratedReport).filter(
        IntegratedReport.report_id == report_id,
        IntegratedReport.status == 1
    ).all()
    
    for old in old_integrated:
        old.status = 0
    
    # TODO: 实际整合逻辑，这里简化处理
    # 在实际应用中，这里应该根据业务需求实现文件整合逻辑
    # 这里假设直接将所有文件内容合并
    
    # 创建整合报告文件名
    merchant = db.query(Merchant).filter(Merchant.id == report.merchant_id).first()
    file_name = f"{merchant.name if merchant else '商户'}-{report.report_name}-整合报告.xlsx"
    
    # 模拟整合逻辑
    store_type = files[0].store_type  # 使用第一个文件的存储类型
    file_content = None
    file_path = None
    file_size = sum(file.file_size for file in files)  # 简化处理，直接累加大小
    
    # 创建整合报告记录
    integrated = IntegratedReport(
        report_id=report_id,
        file_name=file_name,
        file_size=file_size,
        file_format="xlsx",  # 假设为Excel文件
        store_type=store_type,
        file_path=file_path,
        report_content=file_content,
        status=1,
        operator=operator,
        integration_time=datetime.now()
    )
    
    db.add(integrated)
    db.commit()
    db.refresh(integrated)
    
    return integrated

def get_integrated_report(db: Session, report_id: int) -> Optional[Dict[str, Any]]:
    """
    获取整合报告
    
    Args:
        db: 数据库会话
        report_id: 报告ID
        
    Returns:
        整合报告信息
    """
    # 查询整合报告
    integrated = db.query(IntegratedReport).filter(
        IntegratedReport.report_id == report_id,
        IntegratedReport.status == 1
    ).first()
    
    if not integrated:
        # 尝试自动整合
        integrated = integrate_report(db, report_id, "system")
        if not integrated:
            return None
    
    # 构建返回数据
    return {
        "id": integrated.id,
        "file_name": integrated.file_name,
        "file_size": integrated.file_size,
        "file_format": integrated.file_format,
        "store_type": integrated.store_type,
        "file_path": integrated.file_path,
        "report_content": integrated.report_content,
        "integration_time": integrated.integration_time
    } 